package com.icongyou.enterprise.talent_analysis.scheduler;

import com.icongyou.enterprise.talent_analysis.entity.WordCloudUpdateQueue;
import com.icongyou.enterprise.talent_analysis.mapper.WordCloudUpdateQueueMapper;
import com.icongyou.enterprise.talent_analysis.service.WordCloudService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

/**
 * 词云图生成调度器测试
 */
@ExtendWith(MockitoExtension.class)
@DisplayName("词云图生成调度器测试")
class WordCloudGenerationSchedulerTest {

    @Mock
    private WordCloudUpdateQueueMapper queueMapper;

    @Mock
    private WordCloudService wordCloudService;

    @InjectMocks
    private WordCloudGenerationScheduler scheduler;

    @BeforeEach
    void setUp() {
        // 初始化设置
    }

    @Test
    @DisplayName("processWordCloudQueue - 队列为空时不处理")
    void testProcessWordCloudQueue_EmptyQueue() {
        // Arrange
        when(queueMapper.selectPendingTasks(10)).thenReturn(Collections.emptyList());

        // Act
        scheduler.processWordCloudQueue();

        // Assert
        verify(queueMapper).selectPendingTasks(10);
        verify(wordCloudService, never()).generateWordCloudSync(any());
    }

    @Test
    @DisplayName("processWordCloudQueue - 处理队列中的任务")
    void testProcessWordCloudQueue_WithTasks() {
        // Arrange
        WordCloudUpdateQueue task1 = createTask(1L, "660e8400-e29b-41d4-a716-446655440105", 0); // 孙七
        WordCloudUpdateQueue task2 = createTask(2L, "660e8400-e29b-41d4-a716-446655440103", 0); // 王五
        
        when(queueMapper.selectPendingTasks(10)).thenReturn(Arrays.asList(task1, task2));
        when(queueMapper.updateToProcessing(anyLong())).thenReturn(1);
        when(wordCloudService.generateWordCloudSync(anyString())).thenReturn(new java.util.HashMap<>());
        when(queueMapper.updateToCompleted(anyLong())).thenReturn(1);

        // Act
        scheduler.processWordCloudQueue();

        // Assert
        verify(queueMapper).selectPendingTasks(10);
        verify(queueMapper).updateToProcessing(1L);
        verify(queueMapper).updateToProcessing(2L);
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105");
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440103");
        verify(queueMapper).updateToCompleted(1L);
        verify(queueMapper).updateToCompleted(2L);
    }

    @Test
    @DisplayName("processWordCloudQueue - 任务失败后重试")
    void testProcessWordCloudQueue_TaskFailure_Retry() {
        // Arrange
        WordCloudUpdateQueue task = createTask(1L, "660e8400-e29b-41d4-a716-446655440105", 1);
        
        when(queueMapper.selectPendingTasks(10)).thenReturn(Collections.singletonList(task));
        when(queueMapper.updateToProcessing(1L)).thenReturn(1);
        when(wordCloudService.generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105"))
            .thenThrow(new RuntimeException("词云生成失败"));
        when(queueMapper.incrementRetryCount(1L)).thenReturn(1);

        // Act
        scheduler.processWordCloudQueue();

        // Assert
        verify(queueMapper).updateToProcessing(1L);
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105");
        verify(queueMapper).incrementRetryCount(1L);
        verify(queueMapper, never()).updateToFailed(anyLong(), anyString());
    }

    @Test
    @DisplayName("processWordCloudQueue - 重试次数超限标记失败")
    void testProcessWordCloudQueue_TaskFailure_MaxRetries() {
        // Arrange
        WordCloudUpdateQueue task = createTask(1L, "660e8400-e29b-41d4-a716-446655440105", 2); // 已重试2次
        
        when(queueMapper.selectPendingTasks(10)).thenReturn(Collections.singletonList(task));
        when(queueMapper.updateToProcessing(1L)).thenReturn(1);
        when(wordCloudService.generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105"))
            .thenThrow(new RuntimeException("词云生成失败"));
        when(queueMapper.incrementRetryCount(1L)).thenReturn(1);
        when(queueMapper.updateToFailed(anyLong(), anyString())).thenReturn(1);

        // Act
        scheduler.processWordCloudQueue();

        // Assert
        verify(queueMapper).updateToProcessing(1L);
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105");
        verify(queueMapper).incrementRetryCount(1L);
        verify(queueMapper).updateToFailed(eq(1L), contains("词云生成失败"));
    }

    @Test
    @DisplayName("processWordCloudQueue - 异常不影响其他任务")
    void testProcessWordCloudQueue_OneTaskFailsOthersContinue() {
        // Arrange
        WordCloudUpdateQueue task1 = createTask(1L, "660e8400-e29b-41d4-a716-446655440105", 0);
        WordCloudUpdateQueue task2 = createTask(2L, "660e8400-e29b-41d4-a716-446655440103", 0);
        
        when(queueMapper.selectPendingTasks(10)).thenReturn(Arrays.asList(task1, task2));
        when(queueMapper.updateToProcessing(anyLong())).thenReturn(1);
        
        // task1 失败
        when(wordCloudService.generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105"))
            .thenThrow(new RuntimeException("失败"));
        // task2 成功
        when(wordCloudService.generateWordCloudSync("660e8400-e29b-41d4-a716-446655440103"))
            .thenReturn(new java.util.HashMap<>());
        
        when(queueMapper.incrementRetryCount(anyLong())).thenReturn(1);
        when(queueMapper.updateToCompleted(anyLong())).thenReturn(1);

        // Act
        scheduler.processWordCloudQueue();

        // Assert
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440105");
        verify(wordCloudService).generateWordCloudSync("660e8400-e29b-41d4-a716-446655440103");
        verify(queueMapper).incrementRetryCount(1L);
        verify(queueMapper).updateToCompleted(2L);
    }

    // ==================== Helper Methods ====================

    private WordCloudUpdateQueue createTask(Long id, String studentId, int retryCount) {
        WordCloudUpdateQueue task = new WordCloudUpdateQueue();
        task.setId(id);
        task.setStudentId(studentId);
        task.setTriggerSource("test");
        task.setStatus("PENDING");
        task.setRetryCount(retryCount);
        task.setCreatedAt(LocalDateTime.now());
        return task;
    }
}
